package com.queue;


import com.linearList.Node;

/**
 * @Author: linKe
 * @Date: 2022/1/1 21:44
 * @FileName: LinkedQueue
 * @version: 1.0
 * @Description: 链式队列实现类
 */
public final class LinkedQueue<T> implements Queue<T> {
    /**
     * front,rear 链式队列的队头结点和队尾结点
     */
    private Node<T> front, rear;

    /**
     * 构造空链式队列
     */
    public LinkedQueue() {
        this.front = this.rear = null;
    }

    /**
     * 判空
     *
     * @return 结果
     */
    @Override
    public boolean isEmpty() {

        //头尾结点同时为null
        return this.front == null && this.rear == null;
    }

    /**
     * x入队
     *
     * @param x 元素值x
     * @return 结果
     */
    @Override
    public boolean add(T x) {
        if (x == null) {
            return false;
            //抛出空对象异常
            //throw new NullPointerException("x==null");
        }
        //初始化插入的结点 并赋值
        Node<T> q = new Node<>(x, null);
        if (this.front == null) {
            //空队插入
            this.front = q;
        } else {
            //队列尾插入
            this.rear.next = q;
        }
        //新插入的结点赋值为队尾
        this.rear = q;
        //返回插入结果
        return true;
    }

    /**
     * 返回队头，没有删除。若队列空，则返回null
     *
     * @return 结果
     */
    @Override
    public T peek() {

        return this.isEmpty() ? null : this.front.data;
    }

    /**
     * 出队，返回队头元素。若队列空返回null
     *
     * @return 结果
     */
    @Override
    public T poll() {

        if (isEmpty()) {
            return null;
        }
        //取得队头元素
        T x = this.front.data;
        //删除队头结点
        this.front = this.front.next;
        //如果队头为空，则将队尾也置于空
        if (this.front == null) {
            this.rear = null;
        }
        return x;
    }

    /**
     * 重写toString
     * 返回队列所有元素的描写字符串，形式为“（，）”，按照队列元素次序
     *
     * @return 结果
     */
    @Override
    public String toString() {
        StringBuilder stringBuffer = new StringBuilder(this.getClass().getName() + "(");
        //i=(i+1)%this.element.length 以模的方式取值
        for (Node<T> p = this.front; p != null; p=p.next) {
            //按照队列次序复制数组元素
            //stringBuffer.append(this.element[i].toString() + ",");
            //字符串追加更改为用api方法
            stringBuffer.append(p.data.toString()).append( ",");

        }
        //将串最后多余的一个字符","改为“）”
        stringBuffer.setCharAt(stringBuffer.length() - 1, ')');
        //由StringBuilder对象构造String对象
        return new String(stringBuffer);
    }
}
